package com.cne.gmail.Gmail.controller;


import com.cne.gmail.Gmail.Excutor.ScheduledExecutor;
import com.cne.gmail.Gmail.Handle.GmailHandle;
import com.cne.gmail.Gmail.Util.CacheUtil;
import com.cne.gmail.Gmail.Util.MakeUserUtil;
import com.cne.gmail.Gmail.Util.ScopesUtil;
import com.cne.gmail.Gmail.dao.AddressRepostitory;
import com.cne.gmail.Gmail.dao.UserMessageRepository;
import com.cne.gmail.Gmail.model.UserModel;
import com.cne.gmail.Gmail.response.GmailServiceResponse;
import com.cne.gmail.Gmail.service.UserService;
import com.cne.gmail.Gmail.threadFactory.importThread;
import com.google.api.client.auth.oauth2.AuthorizationCodeRequestUrl;
import com.google.api.client.auth.oauth2.TokenResponse;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeRequestUrl;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.common.collect.Lists;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.GeneralSecurityException;
import java.util.List;

@Log4j2
@Controller
@Api(description="用户登陆接口")
public class UserController {
    private final String IP="https://www.zhangxuan321.com/getToken";
    private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
    private static  List<String> SCOPES = Lists.newArrayList();
    private static final String CREDENTIALS_FILE_PATH = "/credentials.json";
    @Autowired
    UserService userService;
    @Autowired
    ScheduledExecutor scheduledExecutor;
    @Autowired
    AddressRepostitory repostitory;
    @Autowired
    UserMessageRepository userMessageRepository;
    @ApiOperation(value = "oauth2授权接口")
    @GetMapping("authorization")
    public String authorization( @RequestParam(value="userName",required = true,defaultValue = "tea") String userName ) throws GeneralSecurityException, IOException {
            InputStream in = GmailHandle.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
            GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
            final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
            SCOPES= ScopesUtil.makeScopes();
            GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES).setAccessType("online").build();
            AuthorizationCodeRequestUrl authorizationUrl =
                    flow.newAuthorizationUrl().setRedirectUri(IP);
            String url="https://accounts.google.com/o/oauth2/auth?access_type="+ ((GoogleAuthorizationCodeRequestUrl) authorizationUrl).getAccessType()
                    +"&client_id="+authorizationUrl.getClientId()+"&redirect_uri="+authorizationUrl.getRedirectUri()
                    +"&response_type="+authorizationUrl.getResponseTypes()+"&scope="+authorizationUrl.getScopes()+"&state="+userName;
            return "redirect:"+url;

    }
    @ApiOperation(value = "回调接口，获取accessToken和refreshToken,前端不用做处理",hidden = true)
    @GetMapping("getToken")
    public String returnUrl(@RequestParam String code, @RequestParam String state) throws Exception {
        //大陆环境需要加代理
        //proxyHandler.proxy();
        InputStream in = GmailHandle.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
        GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
        // Build flow and trigger user authorization request.
        final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
        GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES).setAccessType("online").build();
      try {
          TokenResponse response=  flow.newTokenRequest(code).setRedirectUri(IP).execute();
          System.err.println(response.getRefreshToken());
          UserModel user= MakeUserUtil.makeUser(response,state);
          //判断登陆的google邮箱是否有人登陆
          if (userService.getUser(user.getEmailAddress())!=null){
              //更新AccessToken
              userService.updateAccessToken(user);
                  return "redirect:https://www.zhangxuan321.com/login?emailAddress="+user.getEmailAddress()+"&userName="+user.getUserName();
          }else {
              userService.insert(user);
              new Thread(new importThread(userService,user,scheduledExecutor,"INBOX"),user.getEmailAddress()+"INBOX").start();
              new Thread(new importThread(userService,user,scheduledExecutor,"SENT"),user.getEmailAddress()+"SENT").start();
              return "redirect:https://www.zhangxuan321.com/login?emailAddress="+user.getEmailAddress()+"&userName="+user.getUserName();
          }
      }catch (Exception e){
          log.info(e.getMessage());
          return e.getMessage();
      }
    }
    @ApiOperation(value = "登录页面",hidden = true)
    @GetMapping("login")
    @ApiImplicitParams({
            @ApiImplicitParam( name = "emailAddress", value = "邮箱地址", required = true, dataType = "String"),
            @ApiImplicitParam( name = "userName", value = "当前用户", required = true, dataType = "String")
    })
    public String login(@RequestParam String emailAddress, @RequestParam String userName ){
        UserModel result = userMessageRepository.findByUserNameAndEmailAddress(userName, emailAddress);
        Object o = CacheUtil.getCache().get(emailAddress+"_token");
        boolean b=  result.getAccessToken().equals(o);
        //缓存本地token
        CacheUtil.CacheLoginToken(result.getAccessToken());
        if (o!=null&b==false){
            log.info("把过期的token从缓存中移除");
            CacheUtil.removeToken(emailAddress+"_token");
        }
        return "redirect:http://luoji.cne.com:8087/gmail.html#/?token="+result.getAccessToken();
    }
    @ApiOperation(value = "获取当前用户已授权的邮箱",hidden = true)
    @GetMapping("searchByUserName")
    @ApiImplicitParams({
            @ApiImplicitParam( name = "userName", value = "当前用户", required = true, dataType = "String")
    })
    public GmailServiceResponse searchByUserName(@RequestParam String userName){
        GmailServiceResponse response=new GmailServiceResponse();
        List<UserModel> result = userMessageRepository.findByUserName(userName);
        if (result.size()==0){
            response.setMsg("该用户尚未授权过任何的邮箱，请转到授权页面");
            return response;
        }else {
            response.setData(result);
            response.setCode(200);
            return response;
        }
    }


    @GetMapping("delete")
    @ResponseBody
    public void delete(@RequestParam String emailAddress) {
        repostitory.deleteByemailAddress(emailAddress);
    }



    @ApiOperation(value = "验证登录token是否过期")
    @ApiImplicitParams({
            @ApiImplicitParam( name = "token", value = "token值", required = true, dataType = "String")
    })
    @PostMapping("seachByToken")
    @ResponseBody
    public GmailServiceResponse seachByToken(@RequestParam String token){
        GmailServiceResponse response=new GmailServiceResponse();
        boolean result = CacheUtil.GetCacheLoginToken(token);
        if (result==false){
            response.setCode(401);
            response.setSuccess(false);
            response.setMsg("当前用户登录已过期，请重新授权登录");
            return response;
        }else {
            UserModel userMessage = userMessageRepository.findByAccessToken(token);
            if (userMessage==null){
                response.setCode(401);
                response.setSuccess(false);
                response.setMsg("当前token已过期");
                return response;
            }else {
                response.setCode(200);
                response.setSuccess(true);
                response.setData(userMessage);
                return response;
            }
        }
    }
}
